/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: IPC
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-11-02     JasonHu           Init
 */

#ifndef __IPC_H__
#define __IPC_H__

#include <base/list.h>
#include <base/exobj.h>
#include <base/semaphore.h>
#include <base/atomic.h>

#define NX_IPC_NAME_LEN 32
#define NX_IPC_CHANNEL_MAX 65535

#define NX_IPC_THREAD_STACK_SIZE 8192
#define NX_IPC_HELPER_NAME "IpcHelper"

typedef enum
{
    NX_IPC_CHANNEL_INIT = 0,
    NX_IPC_CHANNEL_ACTIVE,
    NX_IPC_CHANNEL_DEACTIVE,
    NX_IPC_CHANNEL_CLOSE,
} NX_IpcChannelState;

typedef struct NX_IpcServer
{
    NX_List list;
    void * handler;
    NX_Size maxClient;
    NX_List clientList; /* list for client */
    NX_Spin lock; /* lock for client list */
    void * thread; /* thread for ipc server */
    void * process; /* process for ipc server */
    NX_Atomic channelCount;
    char name[NX_IPC_NAME_LEN];
} NX_IpcServer;

typedef struct
{
    NX_Addr clientBufAddr;
    NX_Addr serverBufAddr;
    NX_Size size;
} NX_IpcSharedBuf;

typedef struct NX_IpcChannel
{
    NX_List list; /* list for all channel */
    NX_Size returnValue;
    void * serverThread; /* server thread */
    void * clientThread; /* client thread */
    void * shm;
    void * handler; /* user handler */
    NX_Solt clientSolt; /* client thread info in server solt */
    NX_IpcServer * ipc;
    NX_IpcChannelState state;
    NX_IpcSharedBuf buf;
} NX_IpcChannel;

typedef struct NX_IpcMsg
{
    NX_Solt clientSlot;
    NX_Size dataLen;
    NX_Size dataOffset;
    NX_Size soltCount;
    NX_Size capSlotsOffset;
} NX_IpcMsg;

typedef struct
{
    NX_Addr bufAddr;
    NX_Size bufSize;
} NX_IpcClientConfig;

NX_IpcServer * NX_IpcSearch(const char * name);

NX_IpcServer * NX_IpcCreateServer(const char * name,
    void * serverHandler, NX_Size maxClient);
NX_Error NX_IpcDestroyServer(NX_IpcServer * ipc);

NX_IpcChannel * NX_IpcCreateChannel(NX_IpcServer * ipc,
    NX_Addr serverBufAddr, NX_Addr clientBufAddr, NX_Size bufSize);
NX_Error NX_IpcDestroyChannel(NX_IpcChannel * channel);
NX_Error NX_IpcExitServer(NX_IpcServer * ipc);

#endif /* __IPC_H__ */
